.section .text
# 系统启动入口
.global _entry
_entry:
    # 设置各个核启动时栈地址
    la sp, __stack_start
    li a0, 4096
    csrr a1, mhartid
    addi a1, a1, 1
    mul a0, a0, a1
    add sp, sp, a0

    # 清零BSS段
    la t1, __bss_start
    la t2, __bss_end
bss_clear_loop:
    sd zero, 0(t1)
    addi t1, t1, 8
    blt t1, t2, bss_clear_loop

    call init
loop:
    j loop


#  M模式中断和异常入口.
.globl rv_machine_trap_entry
.align 4
rv_machine_trap_entry:
    # 保存原始的栈地址到scratch寄存器中
    csrw mscratch, sp

    # 设置M模式异常处理时栈地址
    la sp, __stack_start
    li a0, 4096
    li a1, 9
    mul a0, a0, a1
    add sp, sp, a0

	# 调用C入口
	call rv_machine_trap

    # 恢复原始栈地址
    csrr sp, mscratch

	mret

#  S模式中断和异常入口.
.globl rv_supervisor_trap_entry
.align 4
rv_supervisor_trap_entry:
    # 保存寄存器上下文
    addi sp, sp, -256
    sd ra, 0(sp)
    sd sp, 8(sp)
    sd gp, 16(sp)
    sd tp, 24(sp)
    sd t0, 32(sp)
    sd t1, 40(sp)
    sd t2, 48(sp)
    sd s0, 56(sp)
    sd s1, 64(sp)
    sd a0, 72(sp)
    sd a1, 80(sp)
    sd a2, 88(sp)
    sd a3, 96(sp)
    sd a4, 104(sp)
    sd a5, 112(sp)
    sd a6, 120(sp)
    sd a7, 128(sp)
    sd s2, 136(sp)
    sd s3, 144(sp)
    sd s4, 152(sp)
    sd s5, 160(sp)
    sd s6, 168(sp)
    sd s7, 176(sp)
    sd s8, 184(sp)
    sd s9, 192(sp)
    sd s10, 200(sp)
    sd s11, 208(sp)
    sd t3, 216(sp)
    sd t4, 224(sp)
    sd t5, 232(sp)
    sd t6, 240(sp)

    # 保存中断返回地址
    csrr a0, sepc
    sd a0, 248(sp)

    # 记录当前进程内核栈地址到进程的kstack成员中
    la a0, proc_current  # a0 = &proc_current
    ld a1, 0(a0)         # a1 = proc_current
    sd sp, 0(a1)         # proc_current->kstack = sp;

	# 调用C入口
	call rv_supervisor_trap

    # 恢复寄存器上下文
    ld ra, 0(sp)
    ld sp, 8(sp)
    ld gp, 16(sp)
    ld tp, 24(sp)
    ld t0, 32(sp)
    ld t1, 40(sp)
    ld t2, 48(sp)
    ld s0, 56(sp)
    ld s1, 64(sp)
    ld a0, 72(sp)
    ld a1, 80(sp)
    ld a2, 88(sp)
    ld a3, 96(sp)
    ld a4, 104(sp)
    ld a5, 112(sp)
    ld a6, 120(sp)
    ld a7, 128(sp)
    ld s2, 136(sp)
    ld s3, 144(sp)
    ld s4, 152(sp)
    ld s5, 160(sp)
    ld s6, 168(sp)
    ld s7, 176(sp)
    ld s8, 184(sp)
    ld s9, 192(sp)
    ld s10, 200(sp)
    ld s11, 208(sp)
    ld t3, 216(sp)
    ld t4, 224(sp)
    ld t5, 232(sp)
    ld t6, 240(sp)
    addi sp, sp, 256

    sret
